#!/bin/bash
{
	#////////////////////////////////////
	# DietPi Function:
	# - Enables control and applies settings for specific hardware.
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	#////////////////////////////////////
	#
	# Usage:
	readonly FP_SCRIPT='/boot/dietpi/func/dietpi-set_hardware'
	readonly AVAIABLE_COMMANDS="
Available commands:
$FP_SCRIPT	enableipv6		enable/disable
$FP_SCRIPT	preferipv4		enable/disable
$FP_SCRIPT	eth-forcespeed		10/100/1000/disable
$FP_SCRIPT	wifimodules		enable/disable/onboard_enable/onboard_disable
$FP_SCRIPT	wificountrycode		GB/US/DE/...
$FP_SCRIPT	bluetooth		enable/disable
$FP_SCRIPT	serialconsole		enable/disable		[tty(S|AMA|SAC)[0-9]] (optional Serial/UART device)
$FP_SCRIPT	i2c			enable/disable/khz
$FP_SCRIPT	spi			enable/disable
$FP_SCRIPT	soundcard		target_card (non-matching name for reset to default). Add '-eq' to target_card string to enable ALSA equalizer on card. HW:x,x (specify target card and device index eg: HW:9,1)
$FP_SCRIPT	remoteir		odroid_remote/justboom_ir_remote # Odroid/RPi only
$FP_SCRIPT	lcdpanel		target_panel (none to remove all)
$FP_SCRIPT	headless		enable/disable
$FP_SCRIPT	gpumemsplit		64/128/256... Range: 16-944, RPi only
$FP_SCRIPT	rpi-camera		enable/disable
$FP_SCRIPT	rpi-opengl		vc4-kms-v3d/vc4-kms-v3d-pi4/vc4-fkms-v3d/disable
$FP_SCRIPT	rpi3_usb_boot		enable
$FP_SCRIPT	rpi-eeprom
"	#////////////////////////////////////

	# Grab Inputs
	INPUT_DEVICE_NAME=${1,,}
	INPUT_DEVICE_VALUE=${2,,}
	# - Support for 1/0 inputs for enable/disable
	if [[ $INPUT_DEVICE_VALUE == '1' ]]; then

		INPUT_DEVICE_VALUE='enable'

	elif [[ $INPUT_DEVICE_VALUE == '0' ]]; then

		INPUT_DEVICE_VALUE='disable'

	fi
	INPUT_ADDITIONAL=$3

	# Import DietPi-Globals --------------------------------------------------------------
	. /boot/dietpi/func/dietpi-globals
	readonly G_PROGRAM_NAME='DietPi-Set_hardware'
	G_CHECK_ROOT_USER
	G_CHECK_ROOTFS_RW
	G_INIT
	# Import DietPi-Globals --------------------------------------------------------------

	# ARMbian uses armbianEnv.txt instead which requires different syntax
	if [[ -f '/boot/armbianEnv.txt' ]]; then

		ARMBIAN=1
		FP_UENV='/boot/armbianEnv.txt'

	# Sparky SBC uEnv.txt has been renamed to uenv.txt, lets support both variants
	else

		ARMBIAN=0
		FP_UENV='/tmp/uEnv.txt'
		for i in /boot/u{e,E}nv.txt; do [[ -f $i ]] && FP_UENV=$i && break; done
		unset i

	fi

	EXIT_CODE=0

	Unknown_Input_Name(){

		G_DIETPI-NOTIFY 2 "Unknown input name ($INPUT_DEVICE_NAME). Nothing has been applied."
		echo "$AVAIABLE_COMMANDS"
		EXIT_CODE=1

	}

	Unknown_Input_Mode(){

		G_DIETPI-NOTIFY 2 "Unknown input value ($INPUT_DEVICE_VALUE). Nothing has been applied."
		echo "$AVAIABLE_COMMANDS"
		EXIT_CODE=1

	}

	Unsupported_Input_Name(){

		G_DIETPI-NOTIFY 2 "Input name ($INPUT_DEVICE_NAME) is not supported by $G_HW_MODEL_NAME. Nothing has been applied."

	}

	Unsupported_Input_Mode(){

		G_DIETPI-NOTIFY 2 "Input value ($INPUT_DEVICE_VALUE) is not supported by $G_HW_MODEL_NAME. Nothing has been applied."

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# rpi-camera
	#/////////////////////////////////////////////////////////////////////////////////////
	RPi_Camera_Main(){

		(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# Remove modules blacklist
			[[ -f '/etc/modprobe.d/dietpi-disable_rpi_camera.conf' ]] && rm /etc/modprobe.d/dietpi-disable_rpi_camera.conf

			# Enable video devices via extended start
			G_CONFIG_INJECT 'start_x=' 'start_x=1' /boot/config.txt

			# Requires 128 MiB memory split at least
			local gpu_mem=$(sed -n '/^[[:blank:]]*gpu_mem[_0-9]*=/{s/^[^=]*=//p;q}' /boot/config.txt)
			(( ${gpu_mem:-0} < 128 )) && INPUT_DEVICE_VALUE=128 Gpu_Memory_Split_Main

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# Comment extended start setting
			sed -i '/^[[:blank:]]*start_x=/c\#start_x=1' /boot/config.txt

			# Add modules blacklist, which are otherwise loaded by default since kernel 4.19
			echo -e 'blacklist bcm2835_codec\nblacklist bcm2835_v4l2' > /etc/modprobe.d/dietpi-disable_rpi_camera.conf

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# rpi3_usb_boot
	#/////////////////////////////////////////////////////////////////////////////////////
	RPi_USB_Boot_Main(){

		[[ $G_HW_MODEL == 3 && $G_HW_MODEL_NAME != *'+'* ]] || { Unsupported_Input_Name; return 1; } # Exit path for non-RPi3 nonplus

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			G_CONFIG_INJECT 'program_usb_boot_mode=' 'program_usb_boot_mode=1' /boot/config.txt

			cat << _EOF_ > /etc/systemd/system/dietpi-rm_program_usb_boot_mode.service
[Unit]
Description=DietPi-rm_program_usb_boot_mode.service
After=dietpi-boot.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=$(command -v sed) -i '/^[[:blank:]]*program_usb_boot_mode=/d' /boot/config.txt
ExecStartPre=$(command -v systemctl) disable dietpi-rm_program_usb_boot_mode
ExecStart=$(command -v rm) /etc/systemd/system/dietpi-rm_program_usb_boot_mode.service

[Install]
WantedBy=multi-user.target
_EOF_
			systemctl daemon-reload
			systemctl enable dietpi-rm_program_usb_boot_mode

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			sed -i '/^[[:blank:]]*program_usb_boot_mode=/d' /boot/config.txt

			if [[ -f '/etc/systemd/system/dietpi-rm_program_usb_boot_mode.service' ]]; then

				systemctl disable dietpi-rm_program_usb_boot_mode
				rm /etc/systemd/system/dietpi-rm_program_usb_boot_mode.service

			fi

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# rpi-eeprom: https://www.raspberrypi.org/documentation/hardware/raspberrypi/booteeprom.md
	#/////////////////////////////////////////////////////////////////////////////////////
	RPi_EEPROM(){

		(( $G_HW_MODEL == 4 )) || { Unsupported_Input_Name; return 1; } # Exit path for non-RPi4

		# Install required APT package, be failsafe and install/upgrade VC firmware and bootloader as well
		G_AGUP
		G_AGI rpi-eeprom libraspberrypi-bin raspberrypi-bootloader

		# Update/flash new bootloader and VL805 USB firmware to EEPROM
		rpi-eeprom-update -a

		# Required? Enable update service to run on every boot
		systemctl enable rpi-eeprom-update

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# gpumemsplit
	#/////////////////////////////////////////////////////////////////////////////////////
	Gpu_Memory_Split_Main()
	{
		(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi

		# https://www.raspberrypi.org/documentation/configuration/config-txt/memory.md
		if disable_error=1 G_CHECK_VALIDINT "$INPUT_DEVICE_VALUE" 16 944
		then
			# Remove overridden "gpu_mem" setting
			grep -q '^[[:blank:]]*gpu_mem=' /boot/config.txt && G_EXEC sed -i '/^[[:blank:]]*gpu_mem=/d' /boot/config.txt

			local gpu_mem=$INPUT_DEVICE_VALUE
			G_CONFIG_INJECT 'gpu_mem_1024=' "gpu_mem_1024=$gpu_mem" /boot/config.txt
			(( $gpu_mem > 448 )) && gpu_mem=448
			G_CONFIG_INJECT 'gpu_mem_512=' "gpu_mem_512=$gpu_mem" /boot/config.txt
			(( $gpu_mem > 192 )) && gpu_mem=192
			G_CONFIG_INJECT 'gpu_mem_256=' "gpu_mem_256=$gpu_mem" /boot/config.txt

			# Disable VCSM if less than 32M are applied, since it is doomed to fail with cut-down firmware loaded.
			if (( $gpu_mem < 32 ))
			then
				# Blacklist kernel module
				G_EXEC eval 'echo '\''blacklist vc_sm_cma'\'' > /etc/modprobe.d/dietpi-disable_vcsm.conf'
				# Disable device via dtoverlay
				G_EXEC_DESC='Compiling device tree overlay: /boot/overlays/dietpi-disable_vcsm.dtbo'
				G_EXEC eval 'dtc -I dts -O dtb -o /boot/overlays/dietpi-disable_vcsm.dtbo <<< '\''/dts-v1/;
/plugin/;
/ {
	compatible = "brcm,bcm2835";
	fragment@0 {
		target-path = "/soc/vcsm";
		__overlay__ {
			status = "disabled";
		};
	};
};'\'''
				G_CONFIG_INJECT 'dtoverlay=dietpi-disable_vcsm' 'dtoverlay=dietpi-disable_vcsm' /boot/config.txt
			else
				grep -q 'dtoverlay=dietpi-disable_vcsm' /boot/config.txt && G_EXEC sed -i '/dtoverlay=dietpi-disable_vcsm/d' /boot/config.txt
				[[ -f '/boot/overlays/dietpi-disable_vcsm.dtbo' ]] && G_EXEC rm /boot/overlays/dietpi-disable_vcsm.dtbo
				[[ -f '/etc/modprobe.d/dietpi-disable_vcsm.conf' ]] && G_EXEC rm /etc/modprobe.d/dietpi-disable_vcsm.conf
			fi
		else
			Unknown_Input_Mode
		fi
	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# headless
	#/////////////////////////////////////////////////////////////////////////////////////
	Headless_Main(){

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# RPi
			if (( $G_HW_MODEL < 10 )); then

				# Apply lowest possible framebuffer size
				G_CONFIG_INJECT 'framebuffer_width=' 'framebuffer_width=16' /boot/config.txt
				G_CONFIG_INJECT 'framebuffer_height=' 'framebuffer_height=16' /boot/config.txt
				G_CONFIG_INJECT 'max_framebuffer_width=' 'max_framebuffer_width=16' /boot/config.txt
				G_CONFIG_INJECT 'max_framebuffer_height=' 'max_framebuffer_height=16' /boot/config.txt
				# - Splash cannot be seen anyway without video output
				G_CONFIG_INJECT 'disable_splash=' 'disable_splash=1' /boot/config.txt
				# - hdmi_blanking should not play a role, however mode 1 should be generally preferred, which on idle disables HDMI output completely instead of just blanking the screen
				G_CONFIG_INJECT 'hdmi_blanking=' 'hdmi_blanking=1' /boot/config.txt
				# - Disable HDMI hotplug detection, which requires it to be generally responsive/active
				G_CONFIG_INJECT 'hdmi_ignore_hotplug=' 'hdmi_ignore_hotplug=1' /boot/config.txt
				# - Disable SDTV on RPi4
				sed -i '/^[[:blank:]]*enable_tvout=/c\#enable_tvout=0' /boot/config.txt

			# Odroid C2
			elif (( $G_HW_MODEL == 12 )); then

				G_CONFIG_INJECT 'setenv nographics ' 'setenv nographics "1"' /boot/boot.ini

			else

				Unsupported_Input_Name

			fi

			G_CONFIG_INJECT 'AUTO_SETUP_HEADLESS=' 'AUTO_SETUP_HEADLESS=1' /boot/dietpi.txt

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# RPi
			if (( $G_HW_MODEL < 10 )); then

				sed -i '/^[[:blank:]]*framebuffer_width=/c\#framebuffer_width=16' /boot/config.txt
				sed -i '/^[[:blank:]]*framebuffer_height=/c\#framebuffer_height=16' /boot/config.txt
				sed -i '/^[[:blank:]]*max_framebuffer_width=/c\#max_framebuffer_width=16' /boot/config.txt
				sed -i '/^[[:blank:]]*max_framebuffer_height=/c\#max_framebuffer_height=16' /boot/config.txt
				sed -i '/^[[:blank:]]*hdmi_blanking=/c\#hdmi_blanking=0' /boot/config.txt
				sed -i '/^[[:blank:]]*hdmi_ignore_hotplug=/c\#hdmi_ignore_hotplug=0' /boot/config.txt
				sed -i '/^[[:blank:]]*enable_tvout=/c\#enable_tvout=0' /boot/config.txt

			# Odroid C2
			elif (( $G_HW_MODEL == 12 )); then

				G_CONFIG_INJECT 'setenv nographics ' 'setenv nographics "0"' /boot/boot.ini

			else

				Unsupported_Input_Name

			fi

			G_CONFIG_INJECT 'AUTO_SETUP_HEADLESS=' 'AUTO_SETUP_HEADLESS=0' /boot/dietpi.txt

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# remoteir
	#/////////////////////////////////////////////////////////////////////////////////////
	RemoteIR_Prereqs(){ G_AG_CHECK_INSTALL_PREREQ lirc; }

	RemoteIR_Reset(){

		# Disable JustBoom
		if (( $G_HW_MODEL < 10 )); then

			if [[ -f '/etc/systemd/system/justboom-ir-mpd.service' ]]; then

				systemctl disable --now justboom-ir-mpd
				rm -R /etc/systemd/system/justboom-ir-mpd.service*

			fi

			sed -i '/^[[:blank:]]*dtoverlay=gpio-ir/d' /boot/config.txt

		# Disable Odroids
		elif (( $G_HW_MODEL < 20 )) && [[ -f '/etc/systemd/system/odroid-remote.service' ]]; then

			systemctl disable --now odroid-remote
			rm -R /etc/systemd/system/odroid-remote.service*

		fi

	}

	RemoteIR_Main(){

		(( $G_HW_MODEL > 19 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-Odroid/non-RPi

		RemoteIR_Reset

		if [[ $INPUT_DEVICE_VALUE == 'odroid_remote' ]]; then

			(( $G_HW_MODEL > 9 )) || { Unsupported_Input_Mode; return 1; } # Exit path for non-Odroid

			RemoteIR_Prereqs

			# XU4 Cloudshell
			if (( $G_HW_MODEL == 11 )); then

				# Modules
				local string='options gpioplug_ir_recv gpio_nr=24 active_low=1'
				G_CONFIG_INJECT "$string" "$string" /etc/modprobe.d/odroid-cloudshell.conf
				G_CONFIG_INJECT 'gpio-ir-recv' 'gpio-ir-recv' /etc/modules
				G_CONFIG_INJECT 'gpioplug-ir-recv' 'gpioplug-ir-recv' /etc/modules

			# C2
			elif (( $G_HW_MODEL == 12 )); then

				# Module
				G_CONFIG_INJECT 'meson_ir' 'meson_ir' /etc/modules

			fi

			# All
			# - systemd
			systemctl enable lircd

			# - Lircd conf for Odroid Remote
			cat << _EOF_ > /etc/lirc/lircd.conf
begin remote

  name lircd.conf
  bits 16
  flags SPACE_ENC|CONST_LENGTH
  eps 30
  aeps 100

  header 9000 4500
  one 563 1688
  zero 563 564
  ptrail 563
  pre_data_bits 16
  pre_data 0x4DB2
  repeat 9000 2250
  toggle_bit_mask 0x0
      begin codes

          KEY_LEFT 0x9966
          KEY_RIGHT 0x837C
          KEY_UP 0x53AC
          KEY_DOWN 0x4BB4
          KEY_ENTER 0x738C
          KEY_HOME 0x41BE
          KEY_MUTE 0x11EE
          KEY_MENU 0xA35C
          KEY_BACK 0x59A6
          KEY_VOLUMEDOWN 0x817E
          KEY_VOLUMEUP 0x01FE
          KEY_POWER 0x3BC4

      end codes

end remote
_EOF_

		elif [[ $INPUT_DEVICE_VALUE == 'justboom_ir_remote' ]]; then

			(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Mode; return 1; } # Exit path for non-RPi

			RemoteIR_Prereqs

			G_CONFIG_INJECT 'dtoverlay=gpio-ir' 'dtoverlay=gpio-ir,gpio_pin=25' /boot/config.txt

			cat << _EOF_ > /etc/lirc/hardware.conf
LIRCD_ARGS="--uinput"
LOAD_MODULES=true
DRIVER="default"
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
LIRCD_CONF=""
LIRCMD_CONF=""
_EOF_

			cat << _EOF_ > /etc/lirc/lircd.conf
begin remote

  name  lircd.conf
  bits            5
  flags RC5|CONST_LENGTH
  eps            30
  aeps          100

  one           921   855
  zero          921   855
  plead         936
  pre_data_bits   8
  pre_data       0xA0
  gap          114211
  toggle_bit_mask 0x800

  suppress_repeat 5
  duty_cycle 300

  begin codes

        KEY_HOME 0x10
        KEY_POWER 0x11
        KEY_MUTE 0x12
        KEY_LEFT 0x13
        KEY_RIGHT 0x14
        KEY_ENTER 0x15
        KEY_MENU 0x16
        KEY_BACK 0x17
        KEY_VOLUMEDOWN 0x18
        KEY_VOLUMEUP 0x19
        KEY_UP 0x1A
        KEY_DOWN 0x1B

  end codes

end remote
_EOF_

			# MPD control
			G_AG_CHECK_INSTALL_PREREQ mpc

			cat << _EOF_ > /root/.lircrc
begin
prog = irexec
button = KEY_ENTER
config = mpc toggle
end
begin
prog = irexec
button = KEY_VOLUMEUP
config = mpc volume +2
end
begin
prog = irexec
button = KEY_VOLUMEDOWN
config = mpc volume -2
end
begin
prog = irexec
button = KEY_RIGHT
config = mpc next
end
begin
prog = irexec
button = KEY_LEFT
config = mpc prev
end
begin
prog = irexec
button = KEY_UP
config = mpc seek +00:00:10
end
begin
prog = irexec
button = KEY_DOWN
config = mpc seek -00:00:10
end
begin
prog = irexec
button = KEY_BACK
config = mpc repeat on
end
begin
prog = irexec
button = KEY_MENU
config = mpc repeat off
end
_EOF_

			# Service
			cat << _EOF_ > /etc/systemd/system/justboom-ir-mpd.service
[Unit]
Description=justboom-ir-mpd (DietPi)
After=sound.target lircd.service lirc.service

[Service]
ExecStart=$(command -v irexec)

[Install]
WantedBy=default.target
_EOF_
			systemctl daemon-reload
			systemctl enable --now justboom-ir-mpd

		elif [[ $INPUT_DEVICE_VALUE != 'none' ]]; then

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Ethernet force link speed
	#/////////////////////////////////////////////////////////////////////////////////////
	Eth_Force_Speed_Main(){

		if disable_error=1 G_CHECK_VALIDINT "$INPUT_DEVICE_VALUE" 1; then

			local speed_mbit=$INPUT_DEVICE_VALUE
			local iface="eth$(mawk 'NR==1' /run/dietpi/.network)"

			cat << _EOF_ > /etc/systemd/system/ethtool_force_speed.service
[Unit]
Description=ethtool force speed (DietPi)
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=$(command -v ethtool) -s $iface speed $speed_mbit duplex full autoneg off

[Install]
WantedBy=ifup@$iface.service
_EOF_
			systemctl daemon-reload
			systemctl enable --now ethtool_force_speed

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then # 0 is converted to "disable"

			if [[ -f '/etc/systemd/system/ethtool_force_speed.service' ]]; then

				systemctl disable --now ethtool_force_speed
				rm -R /etc/systemd/system/ethtool_force_speed.service*

			fi

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# RPi OpenGL
	#/////////////////////////////////////////////////////////////////////////////////////
	RPi_OpenGL_Main(){

		(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi

		# Always remove previous vc4 overlay entry
		sed -i '/^[[:blank:]]*dtoverlay=vc4-/d' /boot/config.txt

		if [[ $INPUT_DEVICE_VALUE == 'vc4-kms-v3d' || $INPUT_DEVICE_VALUE == 'vc4-kms-v3d-pi4' || $INPUT_DEVICE_VALUE == 'vc4-fkms-v3d' ]]; then

			# Failsafe: Switch to correct full KMS overlay based on RPi model
			[[ $G_HW_MODEL != 4 && $INPUT_DEVICE_VALUE == 'vc4-kms-v3d-pi4' ]] && INPUT_DEVICE_VALUE='vc4-kms-v3d'
			[[ $G_HW_MODEK == 4 && $INPUT_DEVICE_VALUE == 'vc4-kms-v3d' ]] && INPUT_DEVICE_VALUE='vc4-kms-v3d-pi4'

			# GL packages
			local libegl1='libegl1'
			(( $G_DISTRO < 5 )) && libegl1+='-mesa'
			G_AG_CHECK_INSTALL_PREREQ libgl1-mesa-dri libgles2 $libegl1 mesa-utils

			G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE" /boot/config.txt

			# Set 1080p by default
			G_CONFIG_INJECT 'framebuffer_width=' 'framebuffer_width=1920' /boot/config.txt
			G_CONFIG_INJECT 'framebuffer_height=' 'framebuffer_height=1080' /boot/config.txt

		elif [[ $INPUT_DEVICE_VALUE != 'disable' ]]; then

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# lcdpanel eg: All non-HDMI/VGA based displays and monitors.
	#/////////////////////////////////////////////////////////////////////////////////////
	Lcd_Panel_Main(){

		local update_dietpitxt=1

		if [[ $INPUT_DEVICE_VALUE == 'odroid-lcd35' ]]; then

			Lcd_Panel_OdroidLCD35_Enable

		elif [[ $INPUT_DEVICE_VALUE == 'waveshare32' ]]; then

			Lcd_Panel_Waveshare32_Enable

		elif [[ $INPUT_DEVICE_VALUE == 'odroid-cloudshell' ]]; then

			Lcd_Panel_Odroidcloudshell_Enable

		elif [[ ${INPUT_DEVICE_VALUE,,} == 'esp01215e' ]]; then

			Lcd_Panel_ESP01215E_Enable

		# Disable all
		elif [[ $INPUT_DEVICE_VALUE == 'none' ]]; then

			Lcd_Panel_Waveshare32_Disable
			Lcd_Panel_Odroidcloudshell_Disable
			Lcd_Panel_OdroidLCD35_Disable
			Lcd_Panel_ESP01215E_Disable

		else

			update_dietpitxt=0
			Unknown_Input_Mode

		fi

		# Update dietpi.txt entry?
		(( $update_dietpitxt )) && G_CONFIG_INJECT 'CONFIG_LCDPANEL=' "CONFIG_LCDPANEL=$INPUT_DEVICE_VALUE" /boot/dietpi.txt

	}

	Lcd_Panel_ESP01215E_Enable(){

		G_CONFIG_INJECT 'framebuffer_width=' 'framebuffer_width=1024' /boot/config.txt
		G_CONFIG_INJECT 'framebuffer_height=' 'framebuffer_height=600' /boot/config.txt
		G_CONFIG_INJECT 'SOFTWARE_CHROMIUM_RES_X=' "SOFTWARE_CHROMIUM_RES_X=1024" /boot/dietpi.txt
		G_CONFIG_INJECT 'SOFTWARE_CHROMIUM_RES_Y=' "SOFTWARE_CHROMIUM_RES_Y=600" /boot/dietpi.txt
		G_CONFIG_INJECT 'hdmi_force_hotplug=' 'hdmi_force_hotplug=1' /boot/config.txt
		G_CONFIG_INJECT 'hdmi_group=' 'hdmi_group=2' /boot/config.txt
		G_CONFIG_INJECT 'hdmi_mode=' 'hdmi_mode=87' /boot/config.txt
		G_CONFIG_INJECT 'hdmi_cvt=' 'hdmi_cvt=1024 600 60 6 0 0 0' /boot/config.txt
		G_CONFIG_INJECT 'hdmi_drive=' 'hdmi_drive=1' /boot/config.txt

	}

	Lcd_Panel_ESP01215E_Disable(){

		G_EXEC sed -i '/^[[:blank:]]*hdmi_force_hotplug=/c\#hdmi_force_hotplug=1' /boot/config.txt
		G_EXEC sed -i '/^[[:blank:]]*hdmi_group=/c\#hdmi_group=2' /boot/config.txt
		G_EXEC sed -i '/^[[:blank:]]*hdmi_mode=/c\#hdmi_mode=87' /boot/config.txt
		G_EXEC sed -i '/^[[:blank:]]*hdmi_cvt=/c\#hdmi_cvt=1024 600 60 6 0 0 0' /boot/config.txt
		G_EXEC sed -i '/^[[:blank:]]*hdmi_drive=/c\#hdmi_drive=1' /boot/config.txt

	}

	Lcd_Panel_Xorg_All_Enable(){

		# Xinput calibrator, fbset for con2fbmap
		G_AG_CHECK_INSTALL_PREREQ fbset xinput-calibrator xserver-xorg-input-evdev

		G_EXEC mkdir -p /etc/X11/xorg.conf.d

		# Create desktop icon for xcalibration
		# - NB: libinput replaces this in start menu

	}

	# Waveshare32
	Lcd_Panel_Waveshare32_Enable_X11(){

		cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_xorg.conf
Section "Device"
	Identifier	"Allwinner A10/A13 FBDEV"
	Driver		"fbdev"
	Option		"fbdev" "/dev/fb1"
	Option		"SwapbuffersWait" "true"
EndSection
_EOF_
		cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_calibration.conf
Section "InputClass"
	Identifier	"calibration"
	MatchProduct	"ADS7846 Touchscreen"
	Option		"Calibration" "219 3835 3984 219"
	Option		"SwapAxes" "1"
	Driver		"evdev"
EndSection
_EOF_
	}

	Lcd_Panel_Waveshare32_Enable(){

		(( $G_HW_MODEL > 19 )) && { Unsupported_Input_Mode; return 1; } # Exit path for non-RPi/non-Odroid

		# Disable 1st to reset any existing installations:
		Lcd_Panel_Waveshare32_Disable

		# RPi
		if (( $G_HW_MODEL < 10 )); then

			# X11
			Lcd_Panel_Xorg_All_Enable
			Lcd_Panel_Waveshare32_Enable_X11

			G_EXEC curl -sSfL https://github.com/waveshare/LCD-show/raw/master/waveshare32b-overlay.dtb -o /boot/overlays/waveshare32b.dtbo

			#consoleblank=0 no effect
			G_EXEC sed -i 's/rootwait/rootwait fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo/' /boot/cmdline.txt

			G_CONFIG_INJECT 'dtparam=i2c_arm=' 'dtparam=i2c_arm=on' /boot/config.txt
			G_CONFIG_INJECT 'dtparam=spi=' 'dtparam=spi=on' /boot/config.txt

			# Set FB to match res
			G_CONFIG_INJECT 'framebuffer_width=' 'framebuffer_width=320' /boot/config.txt
			G_CONFIG_INJECT 'framebuffer_height=' 'framebuffer_height=240' /boot/config.txt
			G_CONFIG_INJECT 'SOFTWARE_CHROMIUM_RES_X=' "SOFTWARE_CHROMIUM_RES_X=320" /boot/dietpi.txt
			G_CONFIG_INJECT 'SOFTWARE_CHROMIUM_RES_Y=' "SOFTWARE_CHROMIUM_RES_Y=240" /boot/dietpi.txt

			G_CONFIG_INJECT 'dtoverlay=waveshare32b' 'dtoverlay=waveshare32b:rotate=270' /boot/config.txt

			# Swap input axis
			G_EXEC sed -i '/"SwapAxes"/c\	Option		"SwapAxes" "1"' /etc/X11/xorg.conf.d/99-waveshare32_calibration.conf

			# Move fb0 xorg.conf out the way: https://github.com/MichaIng/DietPi/issues/767
			[[ -f '/usr/share/X11/xorg.conf.d/99-fbturbo.conf' ]] && G_EXEC mv /usr/share/X11/xorg.conf.d/99-fbturbo.conf /usr/share/X11/99-fbturbo.conf

		# Odroids
		else

			# X11
			Lcd_Panel_Xorg_All_Enable
			Lcd_Panel_Waveshare32_Enable_X11

			# con2fbmap, maps console (1) to panel(2). Run during boot.
			cat << _EOF_ > /etc/systemd/system/con2fbmap.service
[Unit]
Description=con2fbmap

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=$(command -v con2fbmap) 1 2
ExecStop=$(command -v con2fbmap) 1 0

[Install]
WantedBy=multi-user.target
_EOF_
			G_EXEC systemctl daemon-reload
			G_EXEC systemctl enable con2fbmap

			G_CONFIG_INJECT 'spicc' 'spicc' /etc/modules
			G_CONFIG_INJECT 'fbtft_device' 'fbtft_device' /etc/modules

			echo 'options fbtft_device name=odroidc_tft32 rotate=270 gpios=reset:116,dc:115 speed=32000000 cs=0' > /etc/modprobe.d/waveshare32.conf

			# X11
			cat << '_EOF_' > /etc/X11/xorg.conf.d/99-waveshare32_xorg.conf
Section "Device"
	Identifier	"FBDEV"
	Driver		"fbdev"
	Option		"fbdev" "/dev/fb2"
	#Option		"SwapbuffersWait" "true"
EndSection
_EOF_
		fi

	}

	Lcd_Panel_Waveshare32_Disable(){

		# All
		[[ -f '/etc/X11/xorg.conf.d/99-waveshare32_calibration.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-waveshare32_calibration.conf
		[[ -f '/etc/X11/xorg.conf.d/99-waveshare32_xorg.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-waveshare32_xorg.conf
		[[ -f '/usr/share/applications/xinput_calibrator.desktop' ]] && G_EXEC rm /usr/share/applications/xinput_calibrator.desktop

		# RPi
		if (( $G_HW_MODEL < 10 )); then

			[[ -f '/boot/overlays/waveshare32b.dtbo' ]] && G_EXEC rm /boot/overlays/waveshare32b.dtbo
			G_EXEC sed -i 's/ fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo//' /boot/cmdline.txt

			G_EXEC sed -i '/Waveshare 32 LCD/d' /boot/config.txt
			G_EXEC sed -i '/^[[:blank:]]*dtoverlay=waveshare32b/d' /boot/config.txt
			G_EXEC sed -i '/^[[:blank:]]*dtoverlay=ads7846,cs=1,penirq=17/d' /boot/config.txt
			G_EXEC sed -i '/^[[:blank:]]*dtoverlay=w1-gpio-pullup,gpiopin=4,extpullup=1/d' /boot/config.txt

			# Leave these enabled, just in case the user has other hardware that may use them.
			#G_EXEC sed -i '/^[[:blank:]]*dtparam=i2c_arm=/c\dtparam=i2c_arm=on' /boot/config.txt
			#G_EXEC sed -i '/^[[:blank:]]*dtparam=spi=/c\dtparam=spi=on' /boot/config.txt

			# Move fb0 xorg.conf back: https://github.com/MichaIng/DietPi/issues/767
			[[ -f '/usr/share/X11/99-fbturbo.conf' && ! -f '/usr/share/X11/xorg.conf.d/99-fbturbo.conf' ]] && G_EXEC mv /usr/share/X11/99-fbturbo.conf /usr/share/X11/xorg.conf.d/99-fbturbo.conf

		# Odroids
		elif (( $G_HW_MODEL < 20 )); then

			if [[ -f '/etc/systemd/system/con2fbmap.service' ]]; then

				G_EXEC systemctl disable --now con2fbmap
				G_EXEC rm -R /etc/systemd/system/con2fbmap.service*

			fi
			[[ -f '/etc/modprobe.d/waveshare32.conf' ]] && G_EXEC rm /etc/modprobe.d/waveshare32.conf
			G_EXEC sed -i '/^[[:blank:]]*spicc/d' /etc/modules
			G_EXEC sed -i '/^[[:blank:]]*fbtft_device/d' /etc/modules

		fi

	}

	# Odroid Cloudshell
	Lcd_Panel_Odroidcloudshell_Enable(){

		echo 'options fbtft_device name=hktft9340 busnum=1 rotate=270' > /etc/modprobe.d/odroid-cloudshell.conf

		G_CONFIG_INJECT 'spi_s3c64xx' 'spi_s3c64xx' /etc/modules
		G_CONFIG_INJECT 'fbtft_device' 'fbtft_device' /etc/modules
		echo 'fbtft_device' >> /etc/modules # XU4 4.9 workaround: https://github.com/MichaIng/DietPi/issues/926#issuecomment-299480918

	}

	Lcd_Panel_Odroidcloudshell_Disable(){

		[[ -f '/etc/modprobe.d/odroid-cloudshell.conf' ]] && G_EXEC rm /etc/modprobe.d/odroid-cloudshell.conf
		G_EXEC sed -i '/^[[:blank:]]*spi_s3c64xx/d' /etc/modules
		G_EXEC sed -i '/^[[:blank:]]*fbtft_device/d' /etc/modules

		# Cant run it on the fly, locks up device.
		#root@DietPi-XU4:~# modprobe -rf spi_s3c64xx
		#root@DietPi-XU4:~# modprobe -rf fbtft_device
		#Segmentation fault

	}

	# Odroid LCD 3.5
	Lcd_Panel_OdroidLCD35_Enable(){

		(( $G_HW_MODEL > 9 && $G_HW_MODEL < 20 )) || { Unsupported_Input_Mode; return 1; } # Exit path for non-Odroid

		# Reset to disabled
		Lcd_Panel_OdroidLCD35_Disable

		Lcd_Panel_Xorg_All_Enable

		cat << '_EOF_' > /etc/modprobe.d/odroid-lcd35.conf
options fbtft_device name=flexpfb rotate=90
options flexfb chip=ili9488
_EOF_
		local amodules=('fbtft_device' 'flexfb' 'sx865x')

		# C1/2
		(( $G_HW_MODEL == 11 )) || amodules+=('aml_i2c' 'pwm-meson' 'pwm-ctrl')

		for i in "${amodules[@]}"
		do

			# Enable modules now, as we need to detect pwm path for service
			G_EXEC modprobe "$i"
			G_CONFIG_INJECT "$i" "$i" /etc/modules

		done

		# Service
		# - XU4
		if (( $G_HW_MODEL == 11 )); then

			cat << _EOF_ > /etc/systemd/system/odroid-lcd35.service
[Unit]
Description=Odroid LCD 3.5

[Path]
PathExists=/dev/fb2

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=$(command -v setterm) -blank 0 -powersave off
ExecStart=$(command -v con2fbmap) 1 2
StandardOutput=tty

[Install]
WantedBy=multi-user.target
_EOF_
		# - C1/2
		else

			# Detect correct control files: https://github.com/MichaIng/DietPi/issues/2256
			local fp_control='/sys/devices/platform/pwm-ctrl'
			[[ -e '/sys/devices/pwm-ctrl/enable0' ]] && fp_control='/sys/devices/pwm-ctrl'

			cat << _EOF_ > /etc/systemd/system/odroid-lcd35.service
[Unit]
Description=Odroid LCD 3.5

[Path]
PathExists=/dev/fb2

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/dash -c 'echo 500000 > $fp_control/freq0'
ExecStart=/bin/dash -c 'echo 1 > $fp_control/enable0'
ExecStart=/bin/dash -c 'echo 1023 > $fp_control/duty0'
ExecStart=$(command -v setterm) -blank 0 -powersave off
ExecStart=$(command -v con2fbmap) 1 2
StandardOutput=tty

[Install]
WantedBy=multi-user.target
_EOF_
		fi
		G_EXEC systemctl daemon-reload
		G_EXEC systemctl enable odroid-lcd35

		# X.org
		[[ -f '/etc/X11/xorg.conf.d/exynos.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/exynos.conf # XU4

		G_EXEC mkdir -p /etc/X11/xorg.conf.d
		cat << '_EOF_' > /etc/X11/xorg.conf.d/99-odroid-lcd35.conf
Section "Device"
	Identifier	"C fbdev"
	Driver		"fbdev"
	Option		"fbdev" "/dev/fb2"
EndSection
_EOF_
		# Default calibration
		cat << '_EOF_' > /etc/X11/xorg.conf.d/99-calibration.conf
Section "InputClass"
	Identifier	"calibration"
	MatchProduct	"SX865X Touchscreen"
	Option		"Calibration" "3854 155 3880 262"
	Option		"SwapAxes" "0"
EndSection
_EOF_
	}

	Lcd_Panel_OdroidLCD35_Disable(){

		[[ -f '/etc/X11/xorg.conf.d/99-calibration.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-calibration.conf
		[[ -f '/etc/modprobe.d/odroid-lcd35.conf' ]] && G_EXEC rm /etc/modprobe.d/odroid-lcd35.conf
		if [[ -f '/etc/systemd/system/odroid-lcd35.service' ]]; then

			G_EXEC systemctl disable --now odroid-lcd35
			G_EXEC rm -R /etc/systemd/system/odroid-lcd35.service*

		fi
		[[ -f '/etc/X11/xorg.conf.d/99-odroid-lcd35.conf' ]] && G_EXEC rm /etc/X11/xorg.conf.d/99-odroid-lcd35.conf

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# I2C
	#/////////////////////////////////////////////////////////////////////////////////////
	I2c_Main(){

		(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# Check/install pre-reqs
			G_AG_CHECK_INSTALL_PREREQ python3-smbus i2c-tools

			# Kernel modules
			G_CONFIG_INJECT 'i2c-bcm2708' 'i2c-bcm2708' /etc/modules
			G_CONFIG_INJECT 'i2c-dev' 'i2c-dev' /etc/modules

			# config.txt
			G_CONFIG_INJECT 'dtparam=i2c_arm=' 'dtparam=i2c_arm=on' /boot/config.txt
			G_CONFIG_INJECT 'dtparam=i2c1=' 'dtparam=i2c1=on' /boot/config.txt

			# DietPi-Software, set installed
			[[ -f '/boot/dietpi/.installed' ]] && G_EXEC sed -i '/^aSOFTWARE_INSTALL_STATE\[72\]=/c\aSOFTWARE_INSTALL_STATE\[72\]=2' /boot/dietpi/.installed

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# Kernel modules
			G_EXEC sed -i '/^[[:blank:]]*i2c-bcm2708/d' /etc/modules
			G_EXEC sed -i '/^[[:blank:]]*i2c-dev/d' /etc/modules

			# config.txt
			G_CONFIG_INJECT 'dtparam=i2c_arm=' 'dtparam=i2c_arm=off' /boot/config.txt
			G_CONFIG_INJECT 'dtparam=i2c1=' 'dtparam=i2c1=off' /boot/config.txt
			G_CONFIG_INJECT 'dtparam=i2c_arm_baudrate=' 'dtparam=i2c_arm_baudrate=100000' /boot/config.txt

		# Set baudrate (kHz) | valid int
		elif disable_error=1 G_CHECK_VALIDINT "$INPUT_DEVICE_VALUE" 2 10000000; then

			G_CONFIG_INJECT 'dtparam=i2c_arm_baudrate=' "dtparam=i2c_arm_baudrate=$(( $INPUT_DEVICE_VALUE * 1000 ))" /boot/config.txt

			# Inform user
			INPUT_DEVICE_VALUE+=' kHz'

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# SPI: https://github.com/raspberrypi/documentation/tree/master/hardware/raspberrypi/spi
	#/////////////////////////////////////////////////////////////////////////////////////
	SPI_Main(){

		(( $G_HW_MODEL > 9 )) && { Unsupported_Input_Name; return 1; } # Exit path for non-RPi

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# config.txt
			G_CONFIG_INJECT 'dtparam=spi=' 'dtparam=spi=on' /boot/config.txt

			# Enable in runtime seems to be possible?
			#dtparam spi=on

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# config.txt
			G_CONFIG_INJECT 'dtparam=spi=' 'dtparam=spi=off' /boot/config.txt
			G_EXEC sed -i '/^[[:blank:]]*dtoverlay=spi[0-9]-[0-9]cs/d' /boot/config.txt # Alternative SPI interfaces and chip select lines

			# Disable in runtime seems to be possible?
			#dtparam spi=off

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Bluetooth
	#/////////////////////////////////////////////////////////////////////////////////////

	Bluetooth_Main(){

		local aBLUETOOTH_MODULES=(

			'bluetooth'
			'bnep'
			'btbcm' # RPi3 Broadcom onboard
			'rfcomm' # BPi Pro/M2+ and others
			'hidp' # BPi Pro/M2+ and others
			'hci_uart'

		)

		if [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# RPi
			if (( $G_HW_MODEL < 10 )) && (( $G_HW_ONBOARD_WIFI )); then

				systemctl disable --now hciuart 2> /dev/null
				# Disable onboard Bluetooth via device tree overlay
				G_CONFIG_INJECT 'dtoverlay=disable-bt' 'dtoverlay=disable-bt' /boot/config.txt

			# ASUS TB
			elif (( $G_HW_MODEL == 52 )); then

				systemctl disable --now hciuart 2> /dev/null

			# Broadcom-based models that need brcm_patchram_plus
			elif [[ $G_HW_MODEL == 6[12] ]]; then

				systemctl disable --now brcm_patchram_plus 2> /dev/null

			fi

			systemctl disable --now bluetooth 2> /dev/null

			# Unload and blacklist kernel modules, bluetooth last
			> /etc/modprobe.d/dietpi-disable_bluetooth.conf
			for ((i=$(( ${#aBLUETOOTH_MODULES[@]} - 1 )); i>=0; i--))
			do

				modprobe -r "${aBLUETOOTH_MODULES[$i]}" 2> /dev/null
				echo "blacklist ${aBLUETOOTH_MODULES[$i]}" >> /etc/modprobe.d/dietpi-disable_bluetooth.conf

			done

			# Purge packages
			if (( $G_DIETPI_INSTALL_STAGE >= 0 )); then

				G_AGP bluez bluez-firmware pi-bluetooth rtl8723ds-firmware
				G_AGA

			fi

		elif [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# Remove kernel module blacklist
			[[ -f '/etc/modprobe.d/dietpi-disable_bluetooth.conf' ]] && G_EXEC rm /etc/modprobe.d/dietpi-disable_bluetooth.conf

			# RPi
			if (( $G_HW_MODEL < 10 )) && (( $G_HW_ONBOARD_WIFI )); then

				# Login console on ttyAMA0 must be disabled: https://github.com/MichaIng/DietPi/issues/2607#issuecomment-470523194
				if systemctl -q is-active serial-getty@ttyAMA0; then

					G_WHIP_YESNO '[WARNING] A serial login console is currently active on ttyAMA0\n
Do you want to continue and disable the serial login console?' || return 1
					INPUT_DEVICE_VALUE='disable' INPUT_ADDITIONAL='ttyAMA0' Serial_Main

				fi

				# Remove dtoverlay
				G_EXEC sed -i '/^[[:blank:]]*dtoverlay=disable-bt/d' /boot/config.txt

				G_AG_CHECK_INSTALL_PREREQ pi-bluetooth

			else

				# ROCK Pi S: https://wiki.radxa.com/RockpiS/Debian#Bluetooth
				local rockpis
				(( $G_HW_MODEL == 73 )) && apt-cache show rtl8723ds-firmware &> /dev/null && rockpis='rtl8723ds-firmware'

				# bluez-firmware: BCM203x dongles: https://packages.debian.org/bluez-firmware
				G_AG_CHECK_INSTALL_PREREQ bluez bluez-firmware $rockpis

			fi

			# Load kernel modules, bluetooth first
			for i in "${aBLUETOOTH_MODULES[@]}"
			do

				modprobe "$i" 2> /dev/null

			done

			# Failsafe: Unblock all Bluetooth adapters if rfkill is installed
			command -v rfkill > /dev/null && rfkill unblock bluetooth

			# Broadcom-based models that need brcm_patchram_plus
			if [[ $G_HW_MODEL == 6[12] ]]; then

				G_EXEC systemctl enable --now brcm_patchram_plus

			fi

			G_EXEC systemctl enable --now bluetooth

			# RPi
			(( $G_HW_MODEL > 9 )) || (( ! $G_HW_ONBOARD_WIFI )) || G_EXEC systemctl enable hciuart

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Network
	#/////////////////////////////////////////////////////////////////////////////////////

	Enable_IPv6(){

		if [[ ! -d '/proc/sys/net/ipv6' ]]; then

			G_DIETPI-NOTIFY 1 'IPv6 is not supported or disabled on kernel level. Aborting...'
			EXIT_CODE=1
			return 1

		elif [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			[[ -f '/etc/sysctl.d/dietpi-disable_ipv6.conf' ]] && rm /etc/sysctl.d/dietpi-disable_ipv6.conf
			# - Apply to current session:
			#	- "all" => all existing interfaces
			#	- "default" => all future interfaces
			echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6
			echo 0 > /proc/sys/net/ipv6/conf/default/disable_ipv6
			# - Add IPv6 specific host entries
			G_CONFIG_INJECT '::1[[:blank:]]' '::1 localhost ip6-localhost ip6-loopback' /etc/hosts
			G_CONFIG_INJECT 'ff02::1[[:blank:]]' 'ff02::1 ip6-allnodes' /etc/hosts
			G_CONFIG_INJECT 'ff02::2[[:blank:]]' 'ff02::2 ip6-allrouters' /etc/hosts
			# - dietpi.txt entry
			G_CONFIG_INJECT 'CONFIG_ENABLE_IPV6=' 'CONFIG_ENABLE_IPV6=1' /boot/dietpi.txt

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			echo -e 'net.ipv6.conf.all.disable_ipv6=1\nnet.ipv6.conf.default.disable_ipv6=1' > /etc/sysctl.d/dietpi-disable_ipv6.conf
			sysctl -qp /etc/sysctl.d/dietpi-disable_ipv6.conf
			# - Comment IPv6 specific host entries
			sed -i 's/^::1[[:blank:]]/#::1 /' /etc/hosts
			sed -i 's/^ff02::1[[:blank:]]/#ff02::1 /' /etc/hosts
			sed -i 's/^ff02::2[[:blank:]]/#ff02::2 /' /etc/hosts
			# - dietpi.txt entry
			G_CONFIG_INJECT 'CONFIG_ENABLE_IPV6=' 'CONFIG_ENABLE_IPV6=0' /boot/dietpi.txt
			# - Stop preferring IPv4, if IPv6 is disabled, to reduce obsolete/confusing entries
			INPUT_DEVICE_VALUE='disable' Prefer_IPv4

		else

			Unknown_Input_Mode
			return 1

		fi

		# Failsafe: Comment "disable_ipv6" entries in all other sysctl config files
		local i
		for i in /etc/sysctl{,.d/*}.conf
		do

			[[ $i != '/etc/sysctl.d/dietpi-disable_ipv6.conf' && -f $i ]] || continue
			grep -q '^[[:blank:]]*net.ipv6.conf.[^[:blank:]]*.disable_ipv6[[:blank:]]*=' "$i" || continue
			i=$(readlink -f $i) # https://github.com/MichaIng/DietPi/issues/3003#issuecomment-669464255
			sed -i 's/^[[:blank:]]*net.ipv6.conf.[^[:blank:]]*.disable_ipv6[[:blank:]]*=/#&/' "$i"

		done

	}

	Prefer_IPv4(){

		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# APT force IPv4
			echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99-dietpi-force-ipv4
			# Wget prefer IPv4
			G_CONFIG_INJECT 'prefer-family[[:blank:]]*=' 'prefer-family = IPv4' /etc/wgetrc
			# dietpi.txt entry
			G_CONFIG_INJECT 'CONFIG_PREFER_IPV4=' 'CONFIG_PREFER_IPV4=1' /boot/dietpi.txt

		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# APT allow IPv6
			[[ -f '/etc/apt/apt.conf.d/99-dietpi-force-ipv4' ]] && rm /etc/apt/apt.conf.d/99-dietpi-force-ipv4
			# Wget back to default
			sed -i 's/^[[:blank:]]*prefer-family[[:blank:]]*=/#&/' /etc/wgetrc
			# dietpi.txt entry
			G_CONFIG_INJECT 'CONFIG_PREFER_IPV4=' 'CONFIG_PREFER_IPV4=0' /boot/dietpi.txt

		else

			Unknown_Input_Mode
			return 1

		fi

		# Failsafe: Comment "ForceIPv[46]" entries in all other APT config files
		local i
		for i in /etc/apt/apt.conf.d/*
		do

			[[ ! -f $i || $i == *'99-dietpi-force-ipv4' ]] && continue
			sed -i 's/^[[:blank:]]*Acquire::ForceIPv[46][[:blank:]]*=/#&/' "$i"

		done

	}

	Wifi_Modules_Main(){

		# Estimate module list
		# - All
		local aWIFI_MODULES=('cfg80211')

		# + RPi with onboard WiFi
		if (( $G_HW_ONBOARD_WIFI )); then

			aWIFI_MODULES+=('brcmfmac' 'brcmutil')

		# + OrangePi Zero
		elif (( $G_HW_MODEL == 32 )); then

			aWIFI_MODULES+=('xradio_wlan')

		# + OrangePi Plus / NanoPi K1 Plus
		elif (( $G_HW_MODEL == 34 || $G_HW_MODEL == 67 )); then

			aWIFI_MODULES+=('8189es')

		# + PINE A64 / Pinebook / ASUS Tinker Board (onboard)
		elif (( $G_HW_MODEL == 40 || $G_HW_MODEL == 44 || $G_HW_MODEL == 52 )); then

			aWIFI_MODULES+=('8723bs')

		# + BPi Pro (onboard)
		elif (( $G_HW_MODEL == 51 )); then

			aWIFI_MODULES+=('ap6211')

		# + NanoPi NEO Air / OrangePi Zero Plus 2
		elif (( $G_HW_MODEL == 35 || $G_HW_MODEL == 64 )); then

			# 4.9 uses brcm, only enable dhd for 3.x
			if [[ -d '/boot/dtb' ]]; then

				aWIFI_MODULES+=('brcmfmac' 'brcmutil')

			else

				aWIFI_MODULES+=('dhd')

			fi

		# + NanoPi M3/T3/Fire3
		elif (( $G_HW_MODEL == 62 )); then

			aWIFI_MODULES+=('bcmdhd')

		fi

		# APT packages
		local apackages=('iw' 'wireless-tools' 'crda' 'wpasupplicant')

		if [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# Disable onboard WiFi as well
			(( $G_HW_ONBOARD_WIFI )) && INPUT_DEVICE_VALUE='onboard_disable' Wifi_Modules_Main

			# Reset blacklists and remove powersaving settings
			> /etc/modprobe.d/dietpi-disable_wifi.conf
			[[ -f '/etc/modprobe.d/dietpi-disable_wifi_powersaving.conf' ]] && rm /etc/modprobe.d/dietpi-disable_wifi_powersaving.conf

			# cfg80211 last
			for ((i=$(( ${#aWIFI_MODULES[@]} - 1 )); i>=0; i--))
			do

				echo "blacklist ${aWIFI_MODULES[$i]}" >> /etc/modprobe.d/dietpi-disable_wifi.conf
				modprobe -rf "${aWIFI_MODULES[$i]}" 2> /dev/null

			done

			if G_WHIP_YESNO 'Would you like to purge all WiFi related APT packages?
 - (NOTICE) This will free up space, but an internet-capable Ethernet connection is required to re-enable WiFi functionality.'; then

				G_AGP "${apackages[@]}"
				G_AGA

			fi

		elif [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# Disable known powersaving options for specific chipsets
			cat << _EOF_ > /etc/modprobe.d/dietpi-disable_wifi_powersaving.conf
options 8192cu rtw_power_mgnt=0
options 8188eu rtw_power_mgnt=0
# OPi Plus
options 8189es rtw_power_mgnt=0
# Pine A64
options 8723bs rtw_power_mgnt=0
# Sparky SBC
options wlan_8192eu rtw_power_mgnt=0
# - https://github.com/sparky-sbc/sparky-test/tree/master/rtl8812au
options wlan_8812au rtw_power_mgnt=0
_EOF_

			# Remove blacklists
			[[ -f '/etc/modprobe.d/dietpi-disable_wifi.conf' ]] && rm /etc/modprobe.d/dietpi-disable_wifi.conf

			G_DIETPI-NOTIFY 2 'Please wait, enabling WiFi modules...'

			# cfg80211 first
			for i in "${aWIFI_MODULES[@]}"
			do

				modprobe "$i" 2> /dev/null

			done

			# Delay to allow modules + WPA2-Enterprise being fully loaded and avoid device not found error
			sleep 8

			# Install required APT packages
			G_AG_CHECK_INSTALL_PREREQ "${apackages[@]}" || EXIT_CODE=1

			# Failsafe, unblock all WiFi adapters: https://github.com/MichaIng/DietPi/issues/1627
			command -v rfkill > /dev/null && rfkill unblock wifi

		elif [[ $INPUT_DEVICE_VALUE == 'onboard_enable' ]]; then

			(( $G_HW_ONBOARD_WIFI )) || { Unsupported_Input_Mode; return 1; }

			# Remove dtoverlay
			sed -i '/^[[:blank:]]*dtoverlay=disable-wifi/d' /boot/config.txt

		elif [[ $INPUT_DEVICE_VALUE == 'onboard_disable' ]]; then

			(( $G_HW_ONBOARD_WIFI )) || { Unsupported_Input_Mode; return 1; }

			# Disable onboard WiFi via dtoverlay
			G_CONFIG_INJECT 'dtoverlay=disable-wifi' 'dtoverlay=disable-wifi' /boot/config.txt

		else

			Unknown_Input_Mode

		fi

		# Update our networking file (refresh active wlan index)
		/boot/dietpi/func/obtain_network_details

	}

	Wifi_Countrycode_Main(){

		# Use country code from command input: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
		INPUT_DEVICE_VALUE=${INPUT_DEVICE_VALUE^^} # Needs to be uppercase while all input is made lowercase (ToDo)
		if [[ $INPUT_DEVICE_VALUE == [[:upper:]][[:upper:]] ]]; then

			# Update /etc/default/crda to apply country code via udev rules
			G_CONFIG_INJECT 'REGDOMAIN=' "REGDOMAIN=$INPUT_DEVICE_VALUE" /etc/default/crda || EXIT_CODE=1

			# Apply country code now
			iw reg set "$INPUT_DEVICE_VALUE" || EXIT_CODE=1

			# Update dietpi.txt with new value
			G_CONFIG_INJECT 'AUTO_SETUP_NET_WIFI_COUNTRY_CODE=' "AUTO_SETUP_NET_WIFI_COUNTRY_CODE=$INPUT_DEVICE_VALUE" /boot/dietpi.txt

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# serialconsole
	#/////////////////////////////////////////////////////////////////////////////////////

	Serial_Main(){

		#-------------------------------------------------------------------------------------
		# Enable
		if [[ $INPUT_DEVICE_VALUE == 'enable' ]]; then

			# Enable for specific Serial/UART device
			if [[ $INPUT_ADDITIONAL ]]; then

				# RPi: Warn if on RPi ttyAMA0 is about to be enabled while Bluetooth is up
				if [[ $G_HW_MODEL == [0-9] && $INPUT_ADDITIONAL == 'ttyAMA0' ]] && systemctl -q is-active hciuart; then

					G_WHIP_YESNO '[WARNING] ttyAMA0 is currently used by Bluetooth\n
Do you want to continue and DISABLE Bluetooth now?' || return 1
					INPUT_DEVICE_VALUE='disable' Bluetooth_Main

				fi

				G_DIETPI-NOTIFY 2 "Enabling serial-getty on: /dev/$INPUT_ADDITIONAL"
				G_EXEC systemctl unmask "serial-getty@$INPUT_ADDITIONAL"
				G_EXEC systemctl enable "serial-getty@$INPUT_ADDITIONAL"
				# Start now if device (already) exists
				[[ -e /dev/$INPUT_ADDITIONAL ]] && G_EXEC systemctl start "serial-getty@$INPUT_ADDITIONAL"

				# Allow root login on selected TTY if not enabled by default
				G_CONFIG_INJECT "$INPUT_ADDITIONAL" "$INPUT_ADDITIONAL" /etc/securetty

				# Enable boot messages depending on device
				# - RPi
				if (( $G_HW_MODEL < 10 )); then

					grep -q "console=$INPUT_ADDITIONAL" /boot/cmdline.txt || sed -i "/root=/s/[[:blank:]]*$/ console=$INPUT_ADDITIONAL,115200/" /boot/cmdline.txt

				# - Odroid C2
				elif (( $G_HW_MODEL == 12 )); then

					local old=
					[[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv condev "' /boot/boot.ini) || return 0
					[[ $old == *"console=$INPUT_ADDITIONAL"* ]] && return 0
					old=$(cut -d \" -f 2 <<< "$old")
					G_CONFIG_INJECT 'setenv condev "' "setenv condev \"$old console=$INPUT_ADDITIONAL,115200n8\"" /boot/boot.ini

				# - Odroid XU4
				elif (( $G_HW_MODEL == 11 )); then

					local old=
					[[ -f '/boot/boot.ini' ]] && old=$(grep -m1 '^setenv bootrootfs "' /boot/boot.ini) || return 0
					[[ $old == *"console=$INPUT_ADDITIONAL"* ]] && return 0
					old=$(cut -d \" -f 2 <<< "$old")
					G_CONFIG_INJECT 'setenv bootrootfs "' "setenv bootrootfs \"$old console=$INPUT_ADDITIONAL,115200n8\"" /boot/boot.ini

				# - Armbian: armbianEnv.txt only allows to toggle a fixed serial console depending on device
				elif (( $ARMBIAN )); then

					grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return 0
					if grep -qE 'console=(display|both)' $FP_UENV; then

						G_CONFIG_INJECT 'console=' 'console=both' $FP_UENV

					else

						G_CONFIG_INJECT 'console=' 'console=serial' $FP_UENV

					fi

				# - PINE A64: On Armbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt
				elif (( $G_HW_MODEL == 40 )); then

					[[ ! -f $FP_UENV ]] || grep -q "console=$INPUT_ADDITIONAL" $FP_UENV && return 0
					echo "console=$INPUT_ADDITIONAL,115200n8" >> $FP_UENV

				fi

			# Enable for all detected Serial/UART devices
			else

				# ttyFIQ[0-9]: https://github.com/MichaIng/DietPi/issues/1829#issuecomment-398302497
				for i in /dev/tty{S,AMA,SAC}[0-9]
				do

					[[ -e $i ]] || continue
					INPUT_ADDITIONAL=${i/\/dev\/} Serial_Main

				done

				# On RPi enable primary UART device
				(( $G_HW_MODEL > 9 )) || G_CONFIG_INJECT 'enable_uart=' 'enable_uart=1' /boot/config.txt

				# Update dietpi.txt global var
				G_CONFIG_INJECT 'CONFIG_SERIAL_CONSOLE_ENABLE=' 'CONFIG_SERIAL_CONSOLE_ENABLE=1' /boot/dietpi.txt

			fi

		#-------------------------------------------------------------------------------------
		# Disable
		elif [[ $INPUT_DEVICE_VALUE == 'disable' ]]; then

			# Disable for specific Serial/UART device
			if [[ $INPUT_ADDITIONAL ]]; then

				G_DIETPI-NOTIFY 2 "Disabling serial-getty on: /dev/$INPUT_ADDITIONAL"
				# Stop getty only if not currently attached, failsafe estimation in case of symlinks
				local stop='--now'
				[[ $(readlink -f "$(tty)") == $(readlink -f "/dev/$INPUT_ADDITIONAL") ]] && stop=
				systemctl disable "$stop" "serial-getty@$INPUT_ADDITIONAL"
				# Place a mask only if device exists
				[[ -e /dev/$INPUT_ADDITIONAL ]] && systemctl mask "serial-getty@$INPUT_ADDITIONAL"

				# Disable boot messages depending on device
				# - RPi
				if (( $G_HW_MODEL < 10 )); then

					sed -Ei "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^[:blank:]]*([[:blank:]]*$)?//" /boot/cmdline.txt

				# - Odroid C1/C2/XU4
				elif (( $G_HW_MODEL < 12 )); then

					sed -i "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*//" /boot/boot.ini

				elif (( $ARMBIAN )); then

					grep -q "console=$INPUT_ADDITIONAL" /boot/boot.cmd || return 0
					if grep -qE 'console=(display|both)' $FP_UENV; then

						G_CONFIG_INJECT 'console=' 'console=display' $FP_UENV

					else

						G_CONFIG_INJECT 'console=' 'console=none' $FP_UENV

					fi

				# - PINE A64: On Armbian ttyS0 boot output is forced and custom console is not possible via armbianEnv.txt
				elif (( $G_HW_MODEL == 40 )); then

					sed -i "/^[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*[[:blank:]]*$/d" $FP_UENV # New style: One variable each line
					sed -i "s/[[:blank:]]*console=${INPUT_ADDITIONAL}[^\"[:blank:]]*//" $FP_UENV # Old style: Multiple variables possible each line

				fi

			# Disable for all detected Serial/UART devices
			else

				# ttyFIQ[0-9]: https://github.com/MichaIng/DietPi/issues/1829#issuecomment-398302497
				for i in /dev/tty{S,AMA,SAC}[0-9]
				do

					[[ -e $i ]] || continue
					INPUT_ADDITIONAL=${i/\/dev\/} Serial_Main

				done

				# Cleanup: Disable for left non-existent devices
				for i in /etc/systemd/system/getty.target.wants/serial-getty@*
				do

					[[ -e $i ]] || continue
					i=${i%.service}
					INPUT_ADDITIONAL=${i##*@} Serial_Main

				done

				# On RPi disable primary UART device
				(( $G_HW_MODEL > 9 )) || G_CONFIG_INJECT 'enable_uart=' 'enable_uart=0' /boot/config.txt

				# Update dietpi.txt global var
				G_CONFIG_INJECT 'CONFIG_SERIAL_CONSOLE_ENABLE=' 'CONFIG_SERIAL_CONSOLE_ENABLE=0' /boot/dietpi.txt

			fi

		else

			Unknown_Input_Mode

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# soundcard
	#/////////////////////////////////////////////////////////////////////////////////////
	# Disable all sound cards and reset all settings
	Soundcard_Reset_All(){

		G_DIETPI-NOTIFY 2 'Resetting all sound card settings...'

		# All
		SOUNDCARD_TARGET_CARD=0
		SOUNDCARD_TARGET_DEVICE=0
		ALSA_PLUG_ENABLED=0
		ALSA_EQ_ENABLED=0

		# - Remove previous asound.conf
		[[ -f '/etc/asound.conf' ]] && G_EXEC rm /etc/asound.conf

		# - Remove stored amixer state
		[[ -f '/var/lib/alsa/asound.state' ]] && G_EXEC rm /var/lib/alsa/asound.state

		# - Reset active amixer state
		[[ $INPUT_DEVICE_VALUE != 'none' && -f '/proc/asound/cards' && $(</proc/asound/cards) ]] && alsactl init

		# HW specific
		# - RPi
		if (( $G_HW_MODEL < 10 )); then

			Soundcard_Reset_RPi

		# - Odroid
		elif (( $G_HW_MODEL < 20 )); then

			Soundcard_Reset_Odroid

		# - OPi Zero (H2+)
		elif (( $G_HW_MODEL == 32 )); then

			Soundcard_Reset_H2

		# - H3
		elif (( $G_HW_CPUID == 1 )); then

			Soundcard_Reset_H3

		# - BPi Pro
		elif (( $G_HW_MODEL == 51 )); then

			Soundcard_Reset_BPi_Pro

		# - Sparky SBC
		elif (( $G_HW_MODEL == 70 )); then

			Soundcard_Reset_SparkySBC

		# - ASUS TB
		elif (( $G_HW_MODEL == 52 )); then

			Soundcard_Reset_Asus

		fi

	}

	Soundcard_Reset_RPi(){

		# Remove known sound card device tree overlays
		sed -i '/^[[:blank:]]*dtoverlay=hifiberry-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=iqaudio-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=justboom-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=allo-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=rpi-dac/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=i-sabre-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=dionaudio-/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=googlevoicehat-soundcard/d' /boot/config.txt
		sed -i '/^[[:blank:]]*dtoverlay=applepi-/d' /boot/config.txt

		# Disable I2S
		sed -i '/^[[:blank:]]*dtparam=i2s=/d' /boot/config.txt

		# Disable HDMI drive
		G_EXEC sed -Ei 's/^[[:blank:]]*(hdmi_drive(:[01])?=.*$)/#\1/' /boot/config.txt

		# Remove overlays to disable HDMI audio and 3.5mm jack
		G_EXEC sed -Ei '/^[[:blank:]]*dtoverlay=dietpi-disable_(hdmi_audio|headphones)/d' /boot/config.txt
		[[ -f '/boot/overlays/dietpi-disable_hdmi_audio.dtbo' ]] && G_EXEC rm /boot/overlays/dietpi-disable_hdmi_audio.dtbo
		[[ -f '/boot/overlays/dietpi-disable_headphones.dtbo' ]] && G_EXEC rm /boot/overlays/dietpi-disable_headphones.dtbo

		# Disable onboard sound
		G_CONFIG_INJECT 'dtparam=audio=' 'dtparam=audio=off' /boot/config.txt

	}

	Soundcard_Reset_Odroid(){

		[[ -f '/var/lib/dietpi/postboot.d/c2_smp.sh' ]] && rm /var/lib/dietpi/postboot.d/c2_smp.sh

		# HiFi shield plus
		sed -i '/^[[:blank:]]*snd-soc-pcm5102/d' /etc/modules
		sed -i '/^[[:blank:]]*snd-soc-odroid-dac/d' /etc/modules

		# HiFi shield 2
		sed -i '/^[[:blank:]]*snd-soc-pcm512x/d' /etc/modules
		sed -i '/^[[:blank:]]*snd-soc-pcm512x-i2c/d' /etc/modules
		sed -i '/^[[:blank:]]*snd-soc-odroid-dac2/d' /etc/modules
		if [[ -f '/etc/systemd/system/odroid-hifishield2.service' ]]; then

			systemctl disable --now odroid-hifishield2
			rm -R /etc/systemd/system/odroid-hifishield2.service*

		fi
		[[ -d '/etc/systemd/system/odroid-hifishield2.service.d' ]] && rm -R /etc/systemd/system/odroid-hifishield2.service.d

	}

	Soundcard_Reset_H2(){

		# Set 3.5mm
		[[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' unmute 2> /dev/null

	}

	Soundcard_Reset_H3(){

		# Set HDMI
		SOUNDCARD_TARGET_CARD=1
		[[ $INPUT_DEVICE_VALUE == 'none' ]] || amixer set -c 0 'Audio lineout' mute 2> /dev/null

	}

	Soundcard_Reset_Asus(){

		# Set HDMI
		SOUNDCARD_TARGET_CARD=1

	}

	Soundcard_Reset_SparkySBC(){

		# Allo Piano DAC
		sed -i '/^[[:blank:]]*snd-soc-allo-piano-dac/d' /etc/modules

		# Disable USB 1.1 compat
		sed -i 's/aotg.aotg1_speed=1/aotg.aotg1_speed=0/' $FP_UENV

		# Set HDMI
		SOUNDCARD_TARGET_DEVICE=1
		[[ $INPUT_DEVICE_VALUE != 'none' && -f '/proc/' ]] || amixer -c 0 sset 'audio output mode switch' 'hdmi'

	}

	Soundcard_Reset_BPi_Pro(){

		# Set 3.5mm: https://github.com/MichaIng/DietPi/issues/732#issuecomment-275915919
		[[ $INPUT_DEVICE_VALUE == 'none' ]] && return

		amixer sset 'Left Mixer Left DAC' off
		amixer sset 'Power Amplifier' 62
		amixer sset 'Power Amplifier DAC' on
		amixer sset 'Power Amplifier Mixer' off
		amixer sset 'Power Amplifier Mute' on
		amixer sset 'Right Mixer Left DAC' off
		amixer sset 'Right Mixer Right DAC' off

	}

	Soundcard_Main(){

		#-----------------------------------------------------------------------------
		# An input is required
		[[ $INPUT_DEVICE_VALUE ]] || Unknown_Input_Mode
		#-----------------------------------------------------------------------------
		# Failsafe: Assure installed alsa-utils, if soundcard has been selected
		[[ $INPUT_DEVICE_VALUE == 'none' ]] || G_AG_CHECK_INSTALL_PREREQ alsa-utils
		# Always reset soundcards and revert back to defaults
		Soundcard_Reset_All
		# Print info
		G_DIETPI-NOTIFY 2 'Applying new sound card settings...'
		# Save selection to dietpi.txt
		G_CONFIG_INJECT 'CONFIG_SOUNDCARD=' "CONFIG_SOUNDCARD=$INPUT_DEVICE_VALUE" /boot/dietpi.txt
		# Return now if no soundcard has been selected
		[[ $INPUT_DEVICE_VALUE == 'none' ]] && return
		#-----------------------------------------------------------------------------
		# Apply specific asound.conf and additional settings
		# - ALSA equalizer enabled?
		if [[ $INPUT_DEVICE_VALUE == *'-eq' ]]; then

			ALSA_EQ_ENABLED=1
			# Remove suffic so it doesn't get sent as a dtoverlay on RPi
			INPUT_DEVICE_VALUE=${INPUT_DEVICE_VALUE%-eq}

		# - ALSA automatic conversion (plug) enabled?
		elif [[ $INPUT_DEVICE_VALUE == *'-plug' ]]; then

			ALSA_PLUG_ENABLED=1
			# Remove suffic so it doesn't get sent as a dtoverlay on RPi
			INPUT_DEVICE_VALUE=${INPUT_DEVICE_VALUE%-plug}

		fi

		# Workaround for RPi VC4 full KMS driver
		# - RPi: An additional HDMI sound device exists as card 0: https://github.com/MichaIng/DietPi/issues/3356#issuecomment-578215611
		(( $G_HW_MODEL < 10 )) && grep -q '^[[:blank:]]*dtoverlay=vc4-kms-v3d' /boot/config.txt && ((SOUNDCARD_TARGET_CARD++))
		# - RPi4: card 1 is additionally used for the second HDMI port: https://github.com/MichaIng/DietPi/issues/4059
		(( $G_HW_MODEL == 4 )) && grep -q '^[[:blank:]]*dtoverlay=vc4-kms-v3d-pi4' /boot/config.txt && ((SOUNDCARD_TARGET_CARD++))

		# - Cards
		case "$INPUT_DEVICE_VALUE" in

			# --------------- Generic ---------------
			# Specific card + device, e.g. from auto-detection
			hw:*)

				SOUNDCARD_TARGET_CARD=$(mawk -F, '{print $1}' <<< "${INPUT_DEVICE_VALUE#hw:}")
				SOUNDCARD_TARGET_DEVICE=$(mawk -F, '{print $2}' <<< "${INPUT_DEVICE_VALUE#hw:}")

			;;

			# Auto detect USB DAC
			usb-dac*)

				local usb_detection_card_index=$([[ -f '/proc/asound/cards' ]] && mawk '/USB/ && $1 == /[0-9]/ {print $1;exit}' /proc/asound/cards)
				if [[ $usb_detection_card_index ]]; then

					SOUNDCARD_TARGET_CARD=$usb_detection_card_index
					SOUNDCARD_TARGET_DEVICE=0

					# Sparky SBC
					if (( $G_HW_MODEL == 70 )); then

						# USB 1.1 compat mode (Sparky currently)
						[[ $INPUT_DEVICE_VALUE == *'1.1' ]] && G_EXEC sed -i 's/aotg\.aotg1_speed=0/aotg.aotg1_speed=1/' $FP_UENV

						# Unmute all (re: @sudeep)
						for x in $(amixer -c "$SOUNDCARD_TARGET_CARD" controls | grep layback)
						do
							G_EXEC amixer -c "$SOUNDCARD_TARGET_CARD" cset "$x" 100%
						done

					# Odroid C2: https://github.com/MichaIng/DietPi/issues/2101
					elif (( $G_HW_MODEL == 12 )); then

						cat << '_EOF_' > /var/lib/dietpi/postboot.d/c2_smp.sh
#!/bin/dash
echo 4 > /proc/irq/63/smp_affinity
echo 8 > /proc/irq/62/smp_affinity
_EOF_
						. /var/lib/dietpi/postboot.d/c2_smp.sh

					fi

				# Not found
				else

					G_DIETPI-NOTIFY 1 'Unable to find any USB DAC on your system, reverting to "none"...'
					EXIT_CODE=1
					G_CONFIG_INJECT 'CONFIG_SOUNDCARD=' 'CONFIG_SOUNDCARD=none' /boot/dietpi.txt
					return

				fi

			;;

			# Intel SST DSP
			intel-sst-dsp) G_AG_CHECK_INSTALL_PREREQ 'firmware-intel-sound';;

			# --------------- Sparky SBC ------------
			# Allo Piano DAC (firmware + module)
			#	snd-soc-allo-piano-dac
			#	snd-soc-allo-piano-dac-plus (2.1)
			snd-soc-allo-piano-dac*)

				if [[ ! -d '/lib/firmware/allo' ]]
				then
					local url='https://raw.githubusercontent.com/sparky-sbc/sparky-test/master/piano-firmware/piano-firmware.tar'
					G_CHECK_URL "$url"
					G_EXEC curl -sSfL "$url" -o package.tar
					G_EXEC tar -xf package.tar -C /lib/
					G_EXEC_NOHALT=1 G_EXEC rm package.tar
				fi

				G_CONFIG_INJECT "$INPUT_DEVICE_VALUE" "$INPUT_DEVICE_VALUE" /etc/modules
				G_EXEC modprobe "$INPUT_DEVICE_VALUE"
				SOUNDCARD_TARGET_CARD=1
				SOUNDCARD_TARGET_DEVICE=0
				G_EXEC amixer -c 0 sset 'audio output mode switch' 'i2s'

			;;

			# Allo Cheapo
			#	allo-cheapo-analogue	# 3.5mm/RCA
			#	allo-cheapo-optical	# Optical out
			allo-cheapo*)

				SOUNDCARD_TARGET_CARD=0
				SOUNDCARD_TARGET_DEVICE=0

				# Vol
				G_EXEC amixer –c 0 set 'DAC PA' 35

				if [[ $INPUT_DEVICE_VALUE == 'allo-cheapo-analogue' ]]; then

					G_EXEC amixer -c 0 sset 'audio output mode switch' 'i2s'

				else

					G_EXEC amixer -c 0 sset 'audio output mode switch' 'spdif'
					SOUNDCARD_TARGET_DEVICE=2

				fi

			;;

			# --------------- RPi -------------------
			# Onboard
			#	rpi-bcm2835-auto
			#	rpi-bcm2835-3.5mm
			#	rpi-bcm2835-hdmi
			rpi-bcm2835-*)

				# Enable onboard audio
				G_CONFIG_INJECT 'dtparam=audio=' 'dtparam=audio=on' /boot/config.txt

				# Force 3.5mm out?
				if [[ $INPUT_DEVICE_VALUE == *'3.5mm' ]]; then

					# Disable HDMI audio via dtoverlay
					G_EXEC_DESC='Compiling device tree overlay: /boot/overlays/dietpi-disable_hdmi_audio.dtbo'
					G_EXEC eval 'dtc -I dts -O dtb -o /boot/overlays/dietpi-disable_hdmi_audio.dtbo <<< '\''/dts-v1/;
/plugin/;
/ {
	compatible = "brcm,bcm2835";
	fragment@0 {
		target = <&audio>;
		__overlay__ {
			brcm,disable-hdmi = <1>;
		};
	};
};'\'''
					G_CONFIG_INJECT 'dtoverlay=dietpi-disable_hdmi_audio' 'dtoverlay=dietpi-disable_hdmi_audio' /boot/config.txt

				# Force HDMI output?
				elif [[ $INPUT_DEVICE_VALUE == *'hdmi' ]]; then

					# Disable headphones via dtoverlay
					G_EXEC_DESC='Compiling device tree overlay: /boot/overlays/dietpi-disable_headphones.dtbo'
					G_EXEC eval 'dtc -I dts -O dtb -o /boot/overlays/dietpi-disable_headphones.dtbo <<< '\''/dts-v1/;
/plugin/;
/ {
	compatible = "brcm,bcm2835";
	fragment@0 {
		target = <&audio>;
		__overlay__ {
			brcm,disable-headphones = <1>;
		};
	};
};'\'''
					G_CONFIG_INJECT 'dtoverlay=dietpi-disable_headphones' 'dtoverlay=dietpi-disable_headphones' /boot/config.txt
					G_CONFIG_INJECT 'hdmi_drive=' 'hdmi_drive=2' /boot/config.txt
					(( $G_HW_MODEL == 4 )) && G_CONFIG_INJECT 'hdmi_drive:1=' 'hdmi_drive:1=2' /boot/config.txt 'hdmi_drive='

				fi

			;;

			# Allo Piano DAC (DSP firmware + dtoverlay)
			#	allo-piano-dac-pcm512x-audio
			#	allo-piano-dac-plus-pcm512x-audio (2.1)
			allo-piano-dac*)

				if [[ ! -d '/lib/firmware/allo' ]]
				then
					local url='https://github.com/allocom/piano-firmware/archive/master.tar.gz'
					G_CHECK_URL "$url"
					G_EXEC curl -sSfL "$url" -o package.tar.gz
					G_EXEC tar -xf package.tar.gz
					G_EXEC_NOHALT=1 G_EXEC rm package.tar.gz
					G_EXEC mkdir -p /lib/firmware
					G_EXEC mv piano-firmware-master/lib/firmware/allo /lib/firmware/
					G_EXEC_NOHALT=1 G_EXEC rm -R piano-firmware-master
				fi

				G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE" /boot/config.txt

			;;

			# dtoverlay
			#	hifiberry-*
			#	JustBoom-[dac|digi|both]
			#	allo-boss-dac-pcm512x-audio
			#	allo-digione
			#	allo-katana-dac-audio
			#	rpi-dac
			#	i-sabre-q2m
			#	applepi-dac
			#	iqaudio-*
			#	dionaudio-loco(-v2)
			hifiberry-*|justboom-*|allo-*|rpi-dac|i-sabre-q2m|applepi*|iqaudio-*|dionaudio-loco*)

				# Enable dtoverlay
				G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE" /boot/config.txt

			;;

			# dtoverlay + I2S
			#	googlevoicehat-soundcard
			googlevoicehat-soundcard*)

				# Enable dtoverlay + I2S
				G_CONFIG_INJECT 'dtparam=i2s=' 'dtparam=i2s=on' /boot/config.txt
				G_CONFIG_INJECT "dtoverlay=$INPUT_DEVICE_VALUE" "dtoverlay=$INPUT_DEVICE_VALUE" /boot/config.txt

			;;

			# --------------- Odroid ----------------
			odroid-hifishield-plus)

				G_CONFIG_INJECT 'snd-soc-pcm5102' 'snd-soc-pcm5102' /etc/modules
				G_CONFIG_INJECT 'snd-soc-odroid-dac' 'snd-soc-odroid-dac' /etc/modules
				G_EXEC modprobe snd-soc-pcm5102 snd-soc-odroid-dac

				SOUNDCARD_TARGET_CARD=1

			;;

			odroid-hifishield-2)

				G_CONFIG_INJECT 'aml_i2c' 'aml_i2c' /etc/modules
				G_CONFIG_INJECT 'snd-soc-pcm512x' 'snd-soc-pcm512x' /etc/modules
				G_CONFIG_INJECT 'snd-soc-pcm512x-i2c' 'snd-soc-pcm512x-i2c' /etc/modules
				G_CONFIG_INJECT 'snd-soc-odroid-dac2' 'snd-soc-odroid-dac2' /etc/modules
				G_EXEC modprobe aml_i2c snd-soc-pcm512x snd-soc-pcm512x-i2c snd-soc-odroid-dac2

				SOUNDCARD_TARGET_CARD=1

				cat << _EOF_ > /etc/systemd/system/odroid-hifishield2.service
[Unit]
Description=odroid-hifishield2
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/dash -c 'echo pcm5242 0x4c > /sys/class/i2c-adapter/i2c-1/new_device'
ExecStart=$(command -v amixer) -c 1 sset Analogue 0
ExecStart=$(command -v amixer) -c 1 sset Digital 201
ExecStart=$(command -v amixer) -c 1 sset Deemphasis on

[Install]
WantedBy=sound.target
_EOF_
				G_EXEC systemctl daemon-reload
				G_EXEC systemctl enable --now odroid-hifishield2

			;;

			# --------------- H2 --------------------
			h2-hdmi)

				G_EXEC amixer set -c 0 'Audio lineout' mute
				SOUNDCARD_TARGET_CARD=1

			;;

			# --------------- H3 --------------------
			h3-analogue)

				G_EXEC amixer set -c 0 'Audio lineout' unmute
				SOUNDCARD_TARGET_CARD=0

			;;

			# --------------- NanoPi M2/M3 ----------
			s5pxx18-hdmi)

				SOUNDCARD_TARGET_CARD=1

			;;

			# --------------- ASUS TB ---------------
			asus-tb-analogue)

				SOUNDCARD_TARGET_CARD=0
				SOUNDCARD_TARGET_DEVICE=2

			;;

		esac

		# - Apply asound.conf
		if [[ $INPUT_DEVICE_VALUE == 'googlevoicehat-soundcard'* ]]; then

			cat << '_EOF_' > /etc/asound.conf
pcm.softvol {
	type softvol
	slave.pcm dmix
	control {
		name Master
		card 0
	}
}

pcm.micboost {
	type route
	slave.pcm dsnoop
	ttable {
		0.0 30.0
		1.1 30.0
	}
}

pcm.!default {
	type asym
	playback.pcm "plug:softvol"
	capture.pcm "plug:micboost"
}

ctl.!default {
	type hw
	card 0
}
_EOF_
		elif (( $ALSA_EQ_ENABLED )); then

			G_AG_CHECK_INSTALL_PREREQ libasound2-plugin-equal
			# Pre-create config dir
			G_EXEC mkdir -p /var/lib/dietpi/dietpi-config
			G_EXEC chmod 0775 /var/lib/dietpi/dietpi-config
			G_EXEC chown dietpi:dietpi /var/lib/dietpi/dietpi-config
			cat << _EOF_ > /etc/asound.conf
ctl.eq {
	type equal
	controls "/var/lib/dietpi/dietpi-config/.alsaequal.bin"
}

pcm.plugequal {
	type equal
	slave.pcm {
		type hw
		card $SOUNDCARD_TARGET_CARD
		device $SOUNDCARD_TARGET_DEVICE
	}
	controls "/var/lib/dietpi/dietpi-config/.alsaequal.bin"
}

pcm.!default {
	type plug
	slave.pcm plugequal
	slave.channels 2
}

ctl.!default {
	type hw
	card $SOUNDCARD_TARGET_CARD
}
_EOF_
		elif (( $ALSA_PLUG_ENABLED )); then

			cat << _EOF_ > /etc/asound.conf
pcm.!default {
	type plug
	slave.pcm {
		type hw
		card $SOUNDCARD_TARGET_CARD
		device $SOUNDCARD_TARGET_DEVICE
	}
}

ctl.!default {
	type hw
	card $SOUNDCARD_TARGET_CARD
}
_EOF_
		else

			cat << _EOF_ > /etc/asound.conf
pcm.!default {
	type hw
	card $SOUNDCARD_TARGET_CARD
	device $SOUNDCARD_TARGET_DEVICE
}

ctl.!default {
	type hw
	card $SOUNDCARD_TARGET_CARD
}
_EOF_
		fi

		# Store control states once to assure they are not lost on ungraceful shutdown
		G_EXEC alsactl -g store

		# Buster: Avoid alsa-state.service start if its config file does not exist: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=932209
		(( $G_DISTRO == 5 )) || return
		G_EXEC mkdir -p /etc/systemd/system/alsa-state.service.d
		echo -e '[Unit]\nConditionPathExists=\nConditionPathExists=/etc/alsa/state-daemon.conf' > /etc/systemd/system/alsa-state.service.d/dietpi.conf

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	#-----------------------------------------------------------------------------------
	G_DIETPI-NOTIFY 3 "$G_PROGRAM_NAME" "$INPUT_DEVICE_NAME ($INPUT_DEVICE_VALUE)"

	#-----------------------------------------------------------------------------------
	if [[ $INPUT_DEVICE_NAME == 'soundcard' ]]; then

		Soundcard_Main

	elif [[ $INPUT_DEVICE_NAME == 'serialconsole' ]]; then

		Serial_Main

	elif [[ $INPUT_DEVICE_NAME == 'bluetooth' ]]; then

		Bluetooth_Main || EXIT_CODE=1

	elif [[ $INPUT_DEVICE_NAME == 'wifimodules' ]]; then

		Wifi_Modules_Main

	elif [[ $INPUT_DEVICE_NAME == 'enableipv6' ]]; then

		Enable_IPv6

	elif [[ $INPUT_DEVICE_NAME == 'preferipv4' ]]; then

		Prefer_IPv4

	elif [[ $INPUT_DEVICE_NAME == 'wificountrycode' ]]; then

		Wifi_Countrycode_Main

	elif [[ $INPUT_DEVICE_NAME == 'i2c' ]]; then

		I2c_Main

	elif [[ $INPUT_DEVICE_NAME == 'spi' ]]; then

		SPI_Main

	elif [[ $INPUT_DEVICE_NAME == 'lcdpanel' ]]; then

		Lcd_Panel_Main

	elif [[ $INPUT_DEVICE_NAME == 'rpi-opengl' ]]; then

		RPi_OpenGL_Main

	elif [[ $INPUT_DEVICE_NAME == 'eth-forcespeed' ]]; then

		Eth_Force_Speed_Main

	elif [[ $INPUT_DEVICE_NAME == 'remoteir' ]]; then

		RemoteIR_Main

	elif [[ $INPUT_DEVICE_NAME == 'gpumemsplit' ]]; then

		Gpu_Memory_Split_Main

	elif [[ $INPUT_DEVICE_NAME == 'rpi-camera' ]]; then

		RPi_Camera_Main

	elif [[ $INPUT_DEVICE_NAME == 'rpi3_usb_boot' ]]; then

		RPi_USB_Boot_Main

	elif [[ $INPUT_DEVICE_NAME == 'rpi-eeprom' ]]; then

		RPi_EEPROM

	elif [[ $INPUT_DEVICE_NAME == 'headless' ]]; then

		Headless_Main

	else

		Unknown_Input_Name

	fi

	#-----------------------------------------------------------------------------------
	G_DIETPI-NOTIFY -1 $EXIT_CODE "$INPUT_DEVICE_NAME $INPUT_DEVICE_VALUE"
	#-----------------------------------------------------------------------------------
	exit $EXIT_CODE
	#-----------------------------------------------------------------------------------
}
